import { createRef, RefObject } from 'react'
import type { Result } from 'ahooks/lib/useRequest/src/types'
import { create } from 'zustand'
import { AgGridReact } from '@ag-grid-community/react'

import { DEFAULT_PAGE_SIZE } from '@/utils/pagination'
import { IOrderListItem, IOrderListReq, IOrderListRes } from './interface'
import { normalizeReqData } from './utils'

export type TRequest = Result<IOrderListRes, [IOrderListReq]>

export interface IStore {
  gridRef: RefObject<AgGridReact<IOrderListItem>>
  request?: TRequest
  reqData: IOrderListReq
  /** 非受控 */
  selectedKeys: number[]
  setReqData: (val: Partial<IOrderListReq> | ((prevVal: IOrderListReq) => IOrderListReq)) => void
  /** 非受控 */
  setSelectedKeys: (val: number[]) => void
  /** 选择的运单号 */
  selectWaybillNos: string[]
  /** 设置的运单号 */
  setSelectWaybillNos: (val: string[]) => void
  getData: (scrollToTop?: boolean) => void
}

export const defaultParams: IOrderListReq = {
  waybillNos: undefined,
  fbaId: undefined,
  predictSignStart: undefined,
  predictSignEnd: undefined,
  logisticsStatus: undefined,

  iconType: undefined,

  merchantId: undefined,
  channelId: undefined,
  containerNumber: undefined,
  countryId: undefined,
  destination: undefined,

  businessUserIds: undefined,
  enterpriseConnectorId: undefined,
  dwPredictSignTime: undefined,

  page: 1,
  size: DEFAULT_PAGE_SIZE,
}

export const useBoundStore = create<IStore>((set, get) => {
  return {
    gridRef: createRef(),
    reqData: { ...defaultParams },
    selectedKeys: [],
    selectWaybillNos: [],
    setReqData: val => {
      set(prev => {
        return {
          reqData: {
            ...prev.reqData,
            ...(typeof val === 'function' ? val(prev.reqData) : val),
          },
        }
      })
    },
    setSelectedKeys: val => set({ selectedKeys: val }),
    setSelectWaybillNos: val => set({ selectWaybillNos: val }),
    getData: scrollToTop => {
      const { gridRef, request, reqData } = get()
      request?.run(normalizeReqData(reqData))
      if (scrollToTop) gridRef.current?.api?.ensureIndexVisible(0, 'top')
    },
  }
})
